/*
    Aufgabe 1) Zweidimensionale Arrays - Diverse Methoden
*/

import java.util.Arrays;

public class Aufgabe1 {
    
    private static int[][] genFilledArray(int n) {
        // init
        int sum;
        int[][] gen = new int[n][n];

        // fill array
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                sum = j + i + 1;
                // case 1: sum is not yet bigger or equal n, assign sum
                // case 2: sum is bigger than n, invert by subtracting the
                //         remainder from n
                gen[i][j] = (sum <= n) ?
                        sum :
                        (n - sum % n);
            }
        }

        // return array
        return gen;
    }

    private static int getMaxLen(int[][] arrays) {
        int len = 0;
        for (int[] array : arrays)
            len = Math.max(array.length, len);
        return len;
    }
    
    private static int[][] extendArray(int[][] inputArray) {
        // pad inputArray with zeroes from the left
        int diff;
        int n = inputArray.length;
        int m = getMaxLen(inputArray);
        int[][] extended = new int[n][m];

        // iterate all elements of inputArray
        for (int i = 0; i < n; i++) {
            // calc offset
            diff = inputArray[i].length - m;
            // iterate all elements of target array "extended"
            for (int j = 0; j < m; j++) {
                // as extended's indices can be larger than inputArray indices,
                // extended needs to be padded with zeroes
                // n - j check whether the index is too large to exist for
                // inputArray, to either pad with zero, or to add the
                // corresponding index from inputArray
                extended[i][j] = m - j > inputArray[i].length ?
                        0 :
                        inputArray[i][j + diff];
            }
        }

        return extended;
    }
    
    private static int[] reformatArray(int[][] inputArray) {
        // init
        int n = inputArray.length;
        int[] res = new int[n];
        int sum;
        int m;

        // iterate lines
        for (int i = 0; i < n; i++) {
            m = inputArray[i].length;
            sum = 0;

            for (int j = 0; j < m; j++) {
                // interpret line as binary number, where the smallest index
                // in inputArray represents the MSB of the binary number
                // that is, from (m-1-j) to 0
                sum += inputArray[i][m - 1 - j] == 1 ?
                        (int)Math.pow(2, j) :
                        0;
            }

            // allocate res[i] with interpreted number
            res[i] = sum;
        }

        return res;
    }
    
    private static void printArray(int[][] inputArray) {
        if (inputArray != null) {
            for (int i = 0; i < inputArray.length; i++) {
                for (int j = 0; j < inputArray[i].length; j++) {
                    System.out.print(inputArray[i][j] + "\t");
                }
                System.out.println();
            }
        }
    }
    
    private static void printArray(int[] inputArray) {
        if (inputArray != null) {
            for (int i = 0; i < inputArray.length; i++) {
                System.out.print(inputArray[i] + "\t");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        int[][] array = genFilledArray(2);
        printArray(array);
        assert (Arrays.deepEquals(array, new int[][]{{1, 2}, {2, 1}}));
        System.out.println();
        
        array = genFilledArray(4);
        printArray(array);
        assert (Arrays.deepEquals(array, new int[][]{{1, 2, 3, 4}, {2, 3, 4, 3}, {3, 4, 3, 2}, {4, 3, 2, 1}}));
        System.out.println();
        
        array = genFilledArray(7);
        printArray(array);
        System.out.println();
        
        int[][] array2 = new int[][]{{1, 1, 0}, {1}, {1, 0}, {1, 0, 0, 1}};
        int[][] array2new1 = extendArray(array2);
        printArray(array2new1);
        assert (Arrays.deepEquals(array2new1, new int[][]{{0, 1, 1, 0}, {0, 0, 0, 1}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
        System.out.println();
        
        array2 = new int[][]{{0, 1, 1, 1, 1, 1}, {1, 1}, {1, 0, 0, 0}, {0, 1, 0, 1}, {0}, {1, 0, 1, 1, 0, 0, 1, 1}};
        int[][] array2new2 = extendArray(array2);
        printArray(array2new2);
        assert (Arrays.deepEquals(array2new2, new int[][]{{0, 0, 0, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 1, 1, 0, 0, 1, 1}}));
        System.out.println();
        
        array2 = new int[][]{{1, 3, 2}, {5, 1}, {6, 8, 5, 10}, {9, 4, 1, 9, 2}, {3}, {0, 11, 7, 5, 3, 2, 5}};
        int[][] array2new3 = extendArray(array2);
        printArray(array2new3);
        System.out.println();
        
        int[][] array3 = array2new1.clone();
        int[] array3new = reformatArray(array3);
        printArray(array3new);
        assert (Arrays.equals(array3new, new int[]{6, 1, 2, 9}));
        System.out.println();
        
        array3 = array2new2.clone();
        array3new = reformatArray(array3);
        printArray(array3new);
        assert (Arrays.equals(array3new, new int[]{31, 3, 8, 5, 0, 179}));
        System.out.println();
    }
}



